Como utilizar HttpClient para hacer peticiones HTTP desde Angular
Código de ejemploPrimero en el archivo app.module.ts tenemos que importar el modulo HttpClientModule:
import { HttpClientModule } from '@angular/common/http';
el código del archivo app.module.ts quedaría asi:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { HttpViewComponent } from './http-view/http-view.component';
@NgModule({
declarations: [
AppComponent,
HttpViewComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Para utilizar el HttpClient vamos a usar un componente y un servicio
En el servicio (http-view.service.ts) realizamos el siguiente import:
import { HttpClient } from '@angular/common/http';
En el constructor declaramos una variable HttpClient:
constructor(private http:HttpClient) { }
Y definimos una interfaz, que será la que nos indique la estructura de la informacion que vamos a recibir
export interface messageRequest {
userId: number;
id:number;
title:string;
completed:boolean;
}
ya que recibiremos una peticion json que será tal que así:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Y para terminar definimos una funcion getInfo que usará el objeto HttpClient para hacer la solicitud:
getInfo(){
return this.http.get<messageRequest[]>("https://jsonplaceholder.typicode.com/todos")
}
El metodo http.get tiene que tener un tipo de datos, en este caso le estamos pasando messageRequest[], osea un array de la interfaz que creamos justo antes, esto quiere decir que podremos almacenar varios objetos del tipo messageRequest
El unico parametro que pasamos despues a la funcion get es la direccion a donde realizará la peticion
El archivo del servicio, http-view.service.ts, quedaría asi:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
export interface messageRequest {
userId: number;
id:number;
title:string;
completed:boolean;
}
@Injectable({
providedIn: 'root'
})
export class HttpViewService {
constructor(private http:HttpClient) { }
getInfo(){
return this.http.get<messageRequest[]>("https://jsonplaceholder.typicode.com/todos")
}
}
En el archivo del componente http-view.component.ts, primero creamos una variable de tipo messageRequest[]; que será donde se almacenen los datos que devuelva la peticion
messageObject: messageRequest[];
A continuacion en el constructor creamos una variable httpView de tipo HttpViewService para utilizar nuestro servicio en el componente
constructor( private httpView: HttpViewService )
Y por ultimo en la funcion ngOnInit usamos nuestro servicio para llamar a la funcion getInfo() que nos devolverá un Observavle con el que podremos obtener los datos de la peticion y almacenarlos en nuestra variable messageObject
this.httpView.getInfo().subscribe(data => this.messageObject = data)
El codigo del componente http-view.component.ts quedaría tal que asi:
import { Component, OnInit } from '@angular/core';
import { messageRequest, HttpViewService } from './http-view.service';
@Component({
selector: 'app-http-view',
templateUrl: './http-view.component.html',
styleUrls: ['./http-view.component.css']
})
export class HttpViewComponent implements OnInit {
messageObject: messageRequest[];
constructor( private httpView: HttpViewService ) {
}
ngOnInit(): void {
this.httpView.getInfo().subscribe(data => this.messageObject = data)
}
}
Una manera alternativa (en verdad es la recomendada), de definir el subscribe es la siguiente:
this.httpView
.getInfo()
.subscribe({
next: (data) => (this.messageObject = data),
error: (error) => console.log(error),
complete: () => console.log("complete")
});
Esta implementación nos permite coger el valor de la respuesta next, del error error y de finalización de la solicitud complete
Y por ultimo solo tenemos que mostrar la información en nuestro template http-view.component.html, usaremos el array messageObject para mostrar todos los datos que ha devuelto la solicitud, en este caso los mostramos en una tabla usando el ngFor:
<table border="solid">
<tr *ngFor="let message of messageObject">
<td>{{message.id}}</td>
<td>{{message.title}}</td>
</tr>
</table>
La salida de la aplicacion sería asi:
Para manejar los errores que puede dar una solicitud lo hacemos de la siguiente manera:
getInfo(){
return this.http.get<messageRequest[]>("http://127.0.0.1:8080/api/members")
.pipe(catchError(this.errorHandler))
}
errorHandler(error: HttpErrorResponse){
if (error.status === 0) {
console.error("Cannot connect");
} else {
console.error("Server Error");
}
return throwError(
() => new Error("Error on request")
);
}
Al final de la funcion get encadenamos el siguiente pipe:
.pipe(catchError(this.errorHandler))
En este caso definimos una funcion errorHandler para gestionar los errores
Dentro de la funcion errorHandler comprobamos que tipo de error se produce, si es 0 quiere decir que es un error de que el cliente no se ha podido conectar, si es distinto de 0 es un error del servidor y el numero en si indica el tipo de error, despues el metodo lanza un error indicando que algo ha salido mal (independientemente de que haya sido problema del cliente o del servidor)
El método anterior nos permite manejar los errores en el servicio, pero si queremos tener acceso a los codigos de error que devuelve la petición tenemos que hacerlo de la siguiente manera:
En el servicio añadimos la opción {observe: 'response'} en la solicitud, y no realizamos el pipe como hacíamos antes.
Y ahora al hacer el subscribe podemos acceder a la propiedad status de los objetos, que contiene el código de la solicitud
Http Client | request | solicitud | Angular